﻿using Angle.Krill.Utils;
using AntdUI;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.IO;
using System.Reflection;
using System.Windows.Forms;
using WeifenLuo.WinFormsUI.Docking;

namespace Angle.Krill
{
    internal class DockHelper
    {
        private static string dllPath = Path.Combine(Application.StartupPath, "Angle.Krill.exe");

        /// <summary>
        /// 显示
        /// </summary>
        /// <param name="dockPanel"></param>
        /// <param name="persistString"></param>
        /// <exception cref="NotImplementedException"></exception>
        public static IDockContent GetDockContent(DockPanel dockPanel, string persistString)
        {
            if (string.IsNullOrEmpty(persistString))
            {
                return null;
            }
            PersistParam persistParam = JsonConvert.DeserializeObject<PersistParam>(CodeHelper.Base64Decrypt(persistString));

            var f = ReflectionHelper.Instance(DockHelper.dllPath, persistParam.ClassFullName);
            if (f is DockContent nDockContent)
            {
                IDockContent fDockContent = DockHelper.FindDocument(dockPanel, nDockContent, persistString);
                if (null == fDockContent)
                {
                    nDockContent = SetParam(f.GetType(), persistParam, persistString, nDockContent);

                    return nDockContent;
                }
            }

            return null;
        }
        /// <summary>
        /// 显示
        /// </summary>
        /// <param name="dockPanel">Dock 面板</param>
        /// <param name="dockContent">内容</param>
        /// <param name="dockState"></param>
        /// <param name="additionalParam">自定义参数</param>
        public static void Show(DockPanel dockPanel, Type type, DockState dockState, AdditionalParam additionalParam)
        {
            PersistParam persistParam = new PersistParam()
            {
                ClassFullName = type.FullName,
                AdditionalParam = additionalParam
            };

            string tag = CodeHelper.Base64Encrypt(JsonConvert.SerializeObject(persistParam));

            DockHelper.Show(dockPanel, type, dockState, persistParam, tag);
        }

        public static void Show(DockPanel dockPanel, string clsFullName, DockState dockState, AdditionalParam additionalParam)
        {
            Assembly assembly = Assembly.GetExecutingAssembly();

            // 通过 Type 的 FullName 获取 Type 对象
            Type type = assembly.GetType(clsFullName);

            DockHelper.Show(dockPanel, type, dockState, additionalParam);
        }
        public static void Show(DockPanel dockPanel, DockContent dockContent, DockState dockState)
        {
            IDockContent fDockContent = DockHelper.FindDocument(dockPanel, dockContent, dockContent.Tag?.ToString());
            if (null == fDockContent)
            {
                dockContent.Show(dockPanel, dockState);
            }
            else
            {
                fDockContent.DockHandler.Activate();
            }
        }

        private static void Show(DockPanel dockPanel, Type type, DockState dockState, PersistParam persistParam, string tag)
        {
            var f = ReflectionHelper.Instance(DockHelper.dllPath, persistParam.ClassFullName);
            if (f is DockContent nDockContent)
            {
                IDockContent fDockContent = DockHelper.FindDocument(dockPanel, nDockContent, tag);
                if (null == fDockContent)
                {
                    nDockContent = DockHelper.SetParam(type, persistParam, tag, nDockContent);

                    nDockContent.Show(dockPanel, dockState);
                }
                else
                {
                    fDockContent.DockHandler.Activate();
                }
            }
        }

        private static DockContent SetParam(Type type, PersistParam persistParam, string tag, DockContent nDockContent)
        {
            AdditionalParam additionalParam = persistParam.AdditionalParam;

            if (null != additionalParam.Data)
            {
                nDockContent = ReflectionHelper.Instance(type, additionalParam.Data) as DockContent;
            }
            nDockContent.Icon = ImageHelper.GetIcon(additionalParam.Icon);
            if (!string.IsNullOrEmpty(additionalParam.Text))
            {
                nDockContent.Text = additionalParam.Text;
            }
            nDockContent.Tag = tag;

            return nDockContent;
        }

        /// <summary>
        /// 在DockPanel查询指定Text标题内容窗体界面
        /// </summary>
        /// <param name="dockPanel">面板</param>
        /// <param name="tag">标记</param>
        /// <returns></returns>
        public static IDockContent FindDocument(DockPanel dockPanel, Func<Form, bool> estimateCallback = null)
        {
            foreach (IDockContent content in dockPanel.Contents)
            {
                if (content is Form form)
                {
                    if (estimateCallback?.Invoke(form) ?? false)
                    {
                        return content;
                    }
                }
            }

            return null;
        }
        /// <summary>
        /// 在DockPanel查询指定Text标题内容窗体界面
        /// </summary>
        /// <param name="dockPanel">面板</param>
        /// <param name="container">窗体容器</param>
        /// <param name="tag">标记</param>
        /// <returns></returns>
        public static IDockContent FindDocument(DockPanel dockPanel, Form container, string tag)
        {
            if (dockPanel.DocumentStyle == DocumentStyle.SystemMdi)
            {
                foreach (Form form in container.MdiChildren)
                    if (form.Text == tag)
                        return form as IDockContent;

                return null;
            }
            else
            {
                foreach (IDockContent content in dockPanel.Contents)
                {
                    if (content is Form form)
                    {
                        if (form.Tag?.ToString() == tag)
                        {

                            return content;
                        }
                    }
                }

                return null;
            }
        }
    }

    public class PersistParam
    {
        public string ClassFullName { get; set; }
        public AdditionalParam AdditionalParam { get; set; }
    }

    public class AdditionalParam
    {
        public string Text { get; set; }
        /// <summary>
        /// 图标
        /// </summary>
        public string Icon { get; set; }
        /// <summary>
        /// 自定义数据
        /// </summary>
        public List<AdditionalParamInfo> Data { get; set; }
    }

    public class AdditionalParamInfo
    {
        public string Key { get; set; }
        public object Value { get; set; }
        public Type ValueType
        {
            get
            {
                return Value.GetType();
            }
        }
    }
}
